home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / lists / mint / l_0799 / 685 / asmtrans.zoo / asm.y next >
Encoding:
Text File  |  1993-12-05  |  6.8 KB  |  295 lines

  1. /* asmtrans translator
  2.    Copyright 1992,1993 Eric R. Smith
  3.  
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 1, or (at your option)
  7.    any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18.  
  19. %{
  20. #define YYSTYPE char *
  21.  
  22. #include "asmtrans.h"
  23. %}
  24.  
  25. %token WORD
  26. %token WHITESP
  27. %token EOLN
  28. %token STRING
  29. %token DEFINECMD
  30. %token INCLUDECMD
  31. %token IFDEFCMD
  32. %token IFNDEFCMD
  33. %token ELSECMD
  34. %token ENDIFCMD
  35.  
  36. /* Grammar follows */
  37. %%
  38. input:
  39.         | input line
  40. ;
  41.  
  42. line:    EOLN        { emit($1); }
  43.         /* note that emit() will automatically free the memory,
  44.            and will also check the hidecnt variable */
  45.     | label EOLN    { emit($1); emit($2); }
  46.     | opline EOLN    { emit($1); emit($2); }
  47.     | label opline EOLN    { emit($1); emit($2);
  48.             emit($3); }
  49.     | INCLUDECMD WHITESP STRING EOLN { if (!hidecnt) do_include($3); free($3); }
  50.     | INCLUDECMD WHITESP WORD EOLN { if (!hidecnt) do_include($3); free($3); }
  51.     | DEFINECMD WHITESP WORD WHITESP STRING EOLN {
  52.         if (!hidecnt) do_define($3, $5); free($3); free($5); }
  53.     | DEFINECMD WHITESP WORD WHITESP operand EOLN {
  54.         if (!hidecnt) do_define($3, $5); free($3); free($5); }
  55.     | IFDEFCMD WHITESP WORD EOLN { do_ifdef($3); free($3); }
  56.     | IFNDEFCMD WHITESP WORD EOLN { do_ifndef($3); free($3); }
  57.     | ELSECMD EOLN { do_else(); }
  58.     | ENDIFCMD EOLN { do_endif(); } 
  59. ;
  60.  
  61. opline:    WHITESP opcode        { $$ = do_ops("", $2, "", ""); free($2); }
  62.     | WHITESP opcode WHITESP ops
  63.             { $$ = do_ops("", $2, $3, $4);
  64.              free($2); free($3); free($4); }
  65.     | WORD WHITESP opcode    { $$ = do_ops($1, $3, "", ""); free($1); free($3); }
  66.     | WORD WHITESP opcode WHITESP ops
  67.             { $$ = do_ops($1, $3, $4, $5);
  68.              free($1); free($3); free($4); free($5);}
  69. ;
  70.  
  71. ops: operand { $$ = $1; }
  72.     | operand ',' ops { $$ = concat3($1, ",", $3);
  73.                 free($1); free($3); }
  74. ;
  75.  
  76. opcode: WORD    { $$ = wordlookup($1); free($1); }
  77. ;
  78.  
  79. label: WORD ':' { $$ = concat($1, ":"); free($1); }
  80.  
  81. operand: basic    {$$ = $1; }
  82.     | '#' basic {$$ = immediate($2); free($2); }
  83.     | '(' basic ')' {$$ = indirect($2); free($2); }
  84.     | '(' basic ')' '+' {$$ = postinc($2); free($2); }
  85.     | '-' '(' basic ')' {$$ = predec($3); free($3); }
  86.     | basic '(' basic ')' {$$ = indexed($1, $3); free($1); free($3); }
  87.     | '(' basic ')' WORD {$$ = sizedop($2, $4); free($2); free($4); }
  88.     | basic '(' basic ',' basic ')' {$$ = twoindex($1, $3, $5);
  89.                 free($1); free($3); free($5); }
  90.     | basic '{' basic ':' basic '}' {$$ = bitfield($1, $3, $5);
  91.             free($1); free($3); free($5); }
  92.     | '(' '[' basic ',' basic ']' ',' basic ',' basic ')'
  93.        { $$=postindex($3,$5,$8,$10); 
  94.          free($3); free($5); free($8); free($10); }        
  95.     | '(' '[' basic ',' basic ',' basic ']' ',' basic ')'
  96.        { $$=preindex($3,$5,$7,$10); 
  97.          free($3); free($5); free($7); free($10); }        
  98.     | '(' '[' basic ']' ')'
  99.        { $$=postindex0($3); 
  100.          free($3); }
  101.     | '(' '[' basic ']' ','  basic ')'
  102.        { $$=postindex1($3,$6); 
  103.          free($3); free($6); }                          
  104. ;
  105.  
  106. basic: basexpr { $$ = $1; }
  107.     | basexpr op basic { $$ = concat3($1, $2, $3); free($1); free($2); free($3); }
  108.     | '-' basic { $$ = concat("-", $2); free($2); }
  109.  
  110. basexpr: WORD {$$ = wordlookup($1); free($1); }
  111.     | '$' WORD {$$ = hexop($2); free($2);}
  112. ;
  113.  
  114. op:     '+' { $$ = strdup("+"); }
  115.     | '-' { $$ = strdup("-"); }
  116.     | '*' { $$ = strdup("*"); }
  117.     | '/' { $$ = strdup("/"); }
  118. ;
  119. %%
  120. #include <setjmp.h>
  121.  
  122. jmp_buf start;
  123.  
  124. #ifdef NATIVEATARI
  125. #define STACK 32*1024L
  126. #ifdef LATTICE
  127. long _STACK = STACK;
  128. #endif
  129. #ifdef __GNUC__
  130. long _stksize = STACK;
  131. #endif
  132.  
  133. static void
  134. hit_return()
  135. {
  136.     printf("Hit return to continue\n");
  137.     fflush(stdout);
  138.     getchar();
  139. }
  140. #endif
  141.  
  142. void usage()
  143. {
  144.     fprintf(stderr, "Usage: asmtrans [-gas][-asm][-o outfile] infile\n");
  145.     exit(2);
  146. }
  147.  
  148. int errors = 0;
  149.  
  150. void
  151. do_include(file)
  152.     char *file;
  153. {
  154.     jmp_buf save;
  155.     FILE *oldin, *f;
  156.  
  157.     f = fopen(file, "rt");
  158.     if (!f) {
  159.         perror(file);
  160.         return;
  161.     }
  162.     bcopy(start, save, sizeof(jmp_buf));
  163.     oldin = infile;
  164.     infile = f;
  165.     setjmp(start);
  166.     yyparse();
  167.     fclose(f);
  168.     infile = oldin;
  169.     bcopy(save, start, sizeof(jmp_buf));
  170.     longjmp(start,1);
  171. }
  172.  
  173. /* set up initial definitions based on syntax type */
  174.  
  175. void
  176. do_initial_defs()
  177. {
  178.     if (syntax == GAS) {
  179.         do_define("mmusr", "psr");
  180.         do_define("fpiar", "fpi");
  181.         do_define("XREF", ".globl");
  182.         do_define("XDEF", ".globl");
  183.         do_define("TEXT", ".text");
  184.         do_define("DATA", ".data");
  185.     /* gas doesn't have a .bss directive */
  186.         do_define("BSS", ".data");
  187.         do_define("END", "| END");
  188.         do_define("dc.l", ".long");
  189.         do_define("dc.w", ".word");
  190.         do_define("dc.b", ".byte");
  191.     } else if (syntax == ASM) {
  192.         do_define("TEXT", "SECTION TEXT,CODE");
  193.         do_define("DATA", "SECTION DATA,DATA");
  194.         do_define("BSS", "SECTION BSS,BSS");
  195.     }
  196. }
  197.  
  198. int
  199. main (argc, argv)
  200.     int argc; char **argv;
  201. {
  202.     FILE *f;
  203. #ifdef NATIVEATARI
  204.     if (!argv[0] || !argv[0][0])    /* run from desktop? */
  205.         atexit(hit_return);
  206. #endif
  207.     argv++;
  208.     outfile = stdout;
  209.  
  210.     while (*argv) {
  211.         if (!strcmp(*argv, "-o")) {
  212.             argv++;
  213.             if (*argv == 0) {
  214.                 fprintf(stderr, "missing argument to -o\n");
  215.                 usage();
  216.             }
  217.             f = fopen(*argv, "wt");
  218.             if (!f)
  219.                 perror(*argv);
  220.             else
  221.                 outfile = f;
  222.             argv++;
  223.         } else if (!strcmp(*argv, "-gas")) {
  224.             argv++;
  225.             syntax = GAS;
  226.         } else if (!strcmp(*argv, "-asm")) {
  227.             argv++;
  228.             syntax = ASM;
  229.         } else if (!strcmp(*argv, "-purec")) {
  230.             argv++;
  231.             syntax = PUREC;
  232.         } else if (!strncmp(*argv, "-D", 2)) {
  233.             char *word, *defn;
  234.             word = *argv+2;
  235.             defn = index(word,'=');
  236.             if (defn)
  237.                 *defn++ = '\0';
  238.             else
  239.                 defn = "1";
  240.             if (*word) do_define(word,defn);
  241.             argv++;
  242.         } else if (!strcmp(*argv, "--")) {
  243.             argv++;
  244.             break;
  245.         } else {
  246.             if (**argv == '-') {
  247.                 fprintf(stderr, "unknown option: %s\n",
  248.                     *argv);
  249.                 usage();
  250.             }
  251.             break;
  252.         }
  253.     }
  254.  
  255.     do_initial_defs();
  256.  
  257.     if (*argv == 0) {
  258.         setjmp(start);
  259.         infile = stdin;
  260.         yyparse();
  261.     } else {
  262.         while(*argv) {
  263.         if (!(f = fopen(*argv, "rt")))
  264.             perror(*argv);
  265.         else {
  266.             infile = f;
  267.             setjmp(start);
  268.             yyparse();
  269.             fclose(f);
  270.         }
  271.         argv++;
  272.         }
  273.     }
  274.  
  275.     if (ifstkptr != 0) {
  276.         fputs("%ifdef without matching %endif\n", stderr);
  277.         errors++;
  278.     }
  279.     return errors;
  280. }
  281.  
  282. void
  283. yyerror (s)  /* Called by yyparse on error */
  284.      char *s;
  285. {
  286.     errors++;
  287.     printf("%s\n", s);
  288.     longjmp(start, 1);
  289. }
  290.  
  291. void dbgmsg(s) char *s;
  292. {
  293.     fprintf(stderr, "%s\n", s);
  294. }
  295.